package com.luyuan.crm.promotion.web;

import java.sql.SQLException;

import javax.annotation.Resource;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.hibernate.Criteria;
import org.hibernate.HibernateException;
import org.hibernate.ScrollMode;
import org.hibernate.ScrollableResults;
import org.hibernate.Session;
import org.hibernate.criterion.Order;
import org.hibernate.criterion.Projections;
import org.springframework.context.annotation.Scope;
import org.springframework.orm.hibernate3.HibernateCallback;
import org.springframework.orm.hibernate3.HibernateTemplate;
import org.springframework.stereotype.Component;

import com.luyuan.crm.member.model.Member;
import com.luyuan.crm.promotion.HolidaySalesService;
import com.ruijie.foundation.query.Page;
import com.ruijie.foundation.query.criteria.CriteriaTemplate;
import com.ruijie.web.jsf.action.AbstractAsynOperation;
import com.ruijie.web.jsf.action.AsynOperation;
import com.ruijie.web.jsf.util.AsynModelPanelSupport;

@Component("holidaySalesSupport")
@Scope("view")
public class HolidaySalesSupport extends AsynModelPanelSupport {
    private static final Log logger = LogFactory.getLog(HolidaySalesSupport.class);

    @Resource(name = "holidaySalesService")
    private HolidaySalesService holidaySalesService;

    @Resource(name = "hibernateTemplate")
    private HibernateTemplate hibernateTemplate;

    @Override
    public String getPromptMsg() {
        return "短信发送完成！";
    }

    @Override
    protected AsynOperation getOperatorInstance() {
        return new HolidayOperation();
    }

    @Override
    protected void operate(AsynOperation operator) {
        CriteriaTemplate criteriaTemplate = (CriteriaTemplate) getRequestAttribute("member.criteriaTemplate");
        String sms = (String) getRequestAttribute("holidaySales.sms");
        String remark = (String) getRequestAttribute("holidaySales.remark");
        int integral = (Integer) getRequestAttribute("holidaySales.integral");

        setRequestAttribute("asynSupport", this, true);
        operator.operate(criteriaTemplate, integral, sms, remark);
    }

    class HolidayOperation extends AbstractAsynOperation {

        private String MESSAGE_TEMPLATE = "总共{0}个会员，已经完成{1}会员积分赠送，剩余{2}个会员积分赠送！";

        private String message;

        @Override
        public String getMessages() {
            return message;
        }

        @Override
        public void asynOperate(Object... param) {
            message = "数据准备中......";

            final CriteriaTemplate criteriaTemplate = (CriteriaTemplate) param[0];
            final int integral = (Integer) param[1];
            final String sms = (String) param[2];
            final String remark = (String) param[3];

            try {
                hibernateTemplate.execute(new HibernateCallback() {
                    public Object doInHibernate(Session session) throws HibernateException, SQLException {
                        Criteria criteria = criteriaTemplate.getExecutableCriteria(session);
                        // 获取总行数
                        int rowCount = ((Integer) criteria.setProjection(Projections.rowCount()).uniqueResult())
                                .intValue();
                        if (rowCount == 0) {
                            message = "短信发送完成！";
                            return Page.EMPTY_PAGE;
                        }

                        // 按页检索数据
                        criteria.setProjection(null);
                        criteria.setResultTransformer(Criteria.ROOT_ENTITY);
                        criteria.addOrder(Order.asc("createTime"));

                        ScrollableResults resultList = criteria.scroll(ScrollMode.FORWARD_ONLY);
                        while (resultList.next()) {
                            long remainder = rowCount - resultList.getRowNumber();
                            message = MESSAGE_TEMPLATE.replaceAll("\\{0\\}", String.valueOf(rowCount))
                                    .replaceAll("\\{1\\}", String.valueOf((resultList.getRowNumber())))
                                    .replaceAll("\\{2\\}", String.valueOf(remainder));

                            try {
                                holidaySalesService.bestowIntegral((Member) resultList.get()[0], integral, sms, remark);
                            } catch (Throwable e) {
                            }
                        }

                        message = "短信发送完成！";
                        return null;
                    }
                });
            } catch (Throwable e) {
                message += "异常中断！";
                logger.error("bestowIntegral error!", e);
            }
        }
    }
}
